package org.jeecg.modules.demo.pay.response;

import com.egzosn.pay.common.api.PayConfigStorage;
import com.egzosn.pay.common.api.PayMessageRouter;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.MsgType;
import com.egzosn.pay.common.http.HttpConfigStorage;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.pay.entity.PayConfig;
import org.jeecg.modules.demo.pay.enums.PayType;
import org.jeecg.modules.demo.pay.handler.PaySuccessHandler;
import org.jeecg.common.util.SpringContextHolder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 支付响应对象
 *
 * @author zyf
 */
@Data
@NoArgsConstructor
public class PayResponse {

    /**
     * 支付配置
     */
    private PayConfigStorage storage;
    /**
     * 支付接口
     */
    private PayService service;
    /**
     * 支付路由
     */
    private PayMessageRouter router;
    /**
     * 是否启用代理
     */
    private Boolean proxy = false;

    /**
     * 支付参数
     */
    private Object payInfo;

    private PayConfig payConfig;

    /**
     * 初始化支付配置
     */
    public void init(PayConfig payConfig, String handlerName) {
        //根据不同的账户类型 初始化支付配置
        this.service = payConfig.getPayType().getPayService(payConfig, handlerName);
        this.storage = service.getPayConfigStorage();
        this.payConfig = payConfig;
        //这里设置http请求配置
        if (proxy) {
            service.setRequestTemplateConfigStorage(getHttpConfigStorage(payConfig));
        }else{
            if(oConvertUtils.isNotEmpty(payConfig.getKeystorePath())
                && oConvertUtils.isNotEmpty(payConfig.getStorePassword())){
                HttpConfigStorage store = getHttpConfigStorage(payConfig);
                if(store!=null){
                    service.setRequestTemplateConfigStorage(store);
                }
            }
        }
        buildRouter(payConfig.getId(), handlerName);
    }

    /**
     * 获取http配置，如果配置为null则为默认配置，无代理,无证书的请求方式。
     * 此处非必需
     *
     * @param payConfig 账户信息
     * @return 请求配置
     */
    public HttpConfigStorage getHttpConfigStorage(PayConfig payConfig) {
        HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
        /* 网路代理配置 根据需求进行设置*/
        //http代理地址
       // httpConfigStorage.setHttpProxyHost("192.168.1.69");
        //代理端口
        //httpConfigStorage.setHttpProxyPort(3308);
        //代理用户名
       // httpConfigStorage.setAuthUsername("user");
        //代理密码
       // httpConfigStorage.setAuthPassword("password");
        //设置ssl证书路径 https证书设置 方式二
        if(payConfig.getKeystorePath().indexOf("http")>=0){
            File file = new File(payConfig.getId()+"_"+payConfig.getAppId());
            if(!file.exists()){
                //TODO 密钥文件存储到Redis里面
                file = getInputStreamByUrl(payConfig.getKeystorePath());
            }
            try {
                InputStream in = new FileInputStream(file);
                httpConfigStorage.setKeystore(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }else{
            httpConfigStorage.setKeystore(payConfig.getKeystorePath());
        }
        //设置ssl证书对应的密码
        httpConfigStorage.setStorePassword(payConfig.getStorePassword());
        //设置ssl证书对应的存储方式输入流，这里默认为文件地址
        //httpConfigStorage.setCertStoreType(CertStoreType.STR);
        return httpConfigStorage;
    }


    /**
     * 配置路由
     *
     * @param payId 指定账户id，用户多微信支付多支付宝支付
     */
    private void buildRouter(String payId, String handlerName) {
        router = new PayMessageRouter(this.service);
        PaySuccessHandler payBeforeHandler = SpringContextHolder.getHandler(handlerName, PaySuccessHandler.class);
        router
                .rule()
                //消息类型
                .msgType(MsgType.text.name())
                //支付账户事件类型
                .payType(PayType.aliPay.name())
                //拦截器
                .interceptor(payBeforeHandler)
                //处理器
                .handler(payBeforeHandler)
                .end()
                .rule()
                .msgType(MsgType.xml.name())
                .payType(PayType.wxPay.name())
                .handler(payBeforeHandler)
                .interceptor(payBeforeHandler)
                .end();
    }

    private File getInputStreamByUrl(String url){
        FileOutputStream fileOut = null;
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        try {
            // 建立链接
            URL httpUrl=new URL(url);
            conn=(HttpURLConnection) httpUrl.openConnection();
            //以Post方式提交表单，默认get方式
            //conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            // post方式不能使用缓存
            conn.setUseCaches(false);
            //连接指定的资源
            conn.connect();
            //获取网络输入流
            inputStream=conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            Long tempFileName = System.currentTimeMillis();
            File file = new File(tempFileName+"");
            //写入到文件（注意文件保存路径的后面一定要加上文件的名称）
            fileOut = new FileOutputStream(file);
            BufferedOutputStream bos = new BufferedOutputStream(fileOut);

            byte[] buf = new byte[4096];
            int length = bis.read(buf);
            //保存文件
            while(length != -1)
            {
                bos.write(buf, 0, length);
                length = bis.read(buf);
            }
            bos.close();
            bis.close();
            conn.disconnect();
            return file;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("抛出异常！！");
            return null;
        }
    }

}
